package com.xiaozhichao.databafflesys.admin.controller;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiaozhichao.databafflesys.common.domain.CommonConstant;
import com.xiaozhichao.databafflesys.common.domain.ExceptionEnums;
import com.xiaozhichao.databafflesys.common.domain.PageHelper;
import com.xiaozhichao.databafflesys.common.domain.ResultVo;
import com.xiaozhichao.databafflesys.common.utils.MessageValid;
import com.xiaozhichao.databafflesys.repository.model.BaffleConfig;
import com.xiaozhichao.databafflesys.repository.model.BaffleInterface;
import com.xiaozhichao.databafflesys.repository.model.BaffleMessage;
import com.xiaozhichao.databafflesys.repository.service.BaffleConfigService;
import com.xiaozhichao.databafflesys.repository.service.BaffleInterfaceService;
import com.xiaozhichao.databafflesys.repository.service.BaffleMessageService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author xiaozhichao
 * @since 2021-03-23
 */
@Controller
@RequestMapping("/baffleMessage")
public class BaffleMessageController {

    @Autowired
    BaffleInterfaceService interfaceService;
    @Autowired
    BaffleMessageService messageService;
    @Autowired
    BaffleConfigService configService;

    @RequestMapping("/selectPage")
    @ResponseBody
    public ResultVo selectPage(BaffleMessage entry, PageHelper helper) {
        IPage<BaffleMessage> page = new Page<>(helper.getPage(), helper.getLimit());
        QueryWrapper<BaffleMessage> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(Objects.nonNull(entry.getInterfaceId()), BaffleMessage::getInterfaceId, entry.getInterfaceId())
                .like(!StringUtils.isEmpty(entry.getName()), BaffleMessage::getName, entry.getName());
        IPage<BaffleMessage> pageResult = messageService.page(page, wrapper);
        List<BaffleMessage> result = pageResult.getRecords();
        Iterator<BaffleMessage> iterator = result.iterator();
        JSONArray array = new JSONArray();
        while(iterator.hasNext()){
            BaffleMessage next = iterator.next();
            JSONObject obj = JSONObject.parseObject(JSON.toJSONString(next));
            BaffleInterface byId = interfaceService.getById(next.getInterfaceId());
            obj.put("interfaceName",Objects.nonNull(byId) ? byId.getName() : "");
            array.add(obj);

        }
        return ResultVo.getResult(ExceptionEnums.SUCCESS, pageResult.getTotal(), array);
    }

    @RequestMapping("/add")
    @ResponseBody
    public ResultVo add(BaffleMessage entry,
                        @RequestParam("reqFile") MultipartFile reqFile,
                        @RequestParam("resFile") MultipartFile resFile) throws Exception {
        // 验证
        BaffleInterface baffleInterface = interfaceService.getById(entry.getInterfaceId());
        if (Objects.isNull(baffleInterface)) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "该接口不存在");
        }
        final String reqFileName = reqFile.getOriginalFilename();
        final String resFileName = resFile.getOriginalFilename();
        final String reqType = baffleInterface.getReqType();
        final String resType = baffleInterface.getResType();
        final String reqSuffix = reqFileName.substring(reqFileName.lastIndexOf(".") + 1);
        final String resSuffix = resFileName.substring(resFileName.lastIndexOf(".") + 1);
        if(CommonConstant.queryString.equals(reqType)
                || CommonConstant.formData.equals(reqType)
                || CommonConstant.json.equals(reqType)){
            if(!reqSuffix.equals(CommonConstant.json)){
                return ResultVo.getResult(ExceptionEnums.DO_FAIL, "请求报文文件格式不匹配");
            }
        }else{
            if (!reqSuffix.equals(reqType)) {
                return ResultVo.getResult(ExceptionEnums.DO_FAIL, "请求报文文件格式不匹配");
            }
        }
        if (!CommonConstant.file.equals(resType) && !resSuffix.equals(resType)) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "响应报文文件格式不匹配");
        }
        InputStream resStream = resFile.getInputStream();
        String reqRead = null;
        String resRead = null;
        try {
            reqRead = IoUtil.read(reqFile.getInputStream(), CommonConstant.utf_8);
        } catch (Exception e) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "请求报文文件内容有误");
        }
        if (!CommonConstant.file.equals(resType)) {
            try {
                resRead = IoUtil.read(resStream, CommonConstant.utf_8);
            } catch (Exception e) {
                return ResultVo.getResult(ExceptionEnums.DO_FAIL, "响应报文文件内容有误");
            }
            if (!MessageValid.valid(resType, resRead)) {
                return ResultVo.getResult(ExceptionEnums.DO_FAIL, "响应报文文件内容有误");
            }
        }
        if (!MessageValid.valid(reqType, reqRead)) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "请求报文文件内容有误");
        }

        // 上传路径前缀信息
        QueryWrapper<BaffleConfig> wrapperConfig = new QueryWrapper<>();
        wrapperConfig.lambda()
                .eq(true, BaffleConfig::getCode, CommonConstant.message_path_prefix);
        BaffleConfig config = configService.getOne(wrapperConfig);
        if (Objects.isNull(config)) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "报文上传路径前缀未配置");
        }
        String message_path_prefix = config.getNote();

        // 验证name唯一
        QueryWrapper<BaffleMessage> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(!StringUtils.isEmpty(entry.getName()), BaffleMessage::getName, entry.getName())
                .ne(Objects.nonNull(entry.getId()), BaffleMessage::getId, entry.getId());
        int countName = messageService.count(wrapper);
        if (countName > 0) {
            return ResultVo.getResult(ExceptionEnums.DO_FAIL, "该名称已存在");
        }

        // 保存
        messageService.save(entry);
        // 获取保存的实体
        wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(true, BaffleMessage::getName, entry.getName());
        BaffleMessage one = messageService.getOne(wrapper);
        // 组装 url
        StringBuffer reqUrlSb = new StringBuffer();
        StringBuffer resUrlSb = new StringBuffer();
        StringBuffer urlSb = new StringBuffer();
        urlSb.append(message_path_prefix);
        urlSb.append(baffleInterface.getUri());
        urlSb.append(CommonConstant.uri_spilt);

        reqUrlSb.append(urlSb);
        reqUrlSb.append(CommonConstant.request);
        reqUrlSb.append(one.getId());
        reqUrlSb.append(CommonConstant.type_spilt);
        reqUrlSb.append(reqSuffix);

        resUrlSb.append(urlSb);
        resUrlSb.append(CommonConstant.response);
        resUrlSb.append(one.getId());
        resUrlSb.append(CommonConstant.type_spilt);
        resUrlSb.append(resSuffix);

        FileUtil.writeUtf8String(reqRead, reqUrlSb.toString());
        if (CommonConstant.file.equals(resType)) {
            FileUtil.writeFromStream(resStream, resUrlSb.toString());
        } else {
            FileUtil.writeUtf8String(resRead, resUrlSb.toString());
        }

        one.setReqUrl(reqUrlSb.toString());
        one.setResUrl(resUrlSb.toString());
        // 更新
        messageService.saveOrUpdate(one);
        return ResultVo.getResult(ExceptionEnums.SUCCESS);
    }

    @RequestMapping("/del")
    @ResponseBody
    public ResultVo del(@RequestBody Collection<String> idList) {
        // 删除
        QueryWrapper<BaffleMessage> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(!CollectionUtils.isEmpty(idList), BaffleMessage::getId, idList);
        List<BaffleMessage> oldList = messageService.list(wrapper);
        boolean remove = messageService.remove(wrapper);
        if (remove && !CollectionUtils.isEmpty(oldList)) {
            oldList.stream().forEach(msg -> {
                FileUtil.del(msg.getReqUrl());
                FileUtil.del(msg.getResUrl());
            });
        }
        return ResultVo.getResult(remove ? ExceptionEnums.SUCCESS : ExceptionEnums.DO_FAIL);
    }


}

